home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xarchie-2.0.9 / browser.c < prev    next >
C/C++ Source or Header  |  1995-06-18  |  13KB  |  518 lines

  1. /*
  2.  * browser.c : Device-independent browser routines
  3.  *
  4.  * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
  5.  * 28 Apr 1993: Remove some bogus status0("Ready") calls.
  6.  *  8 Jul 1993: Don't need actions.h.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include "stringdefs.h"
  11. #include "pfs.h"
  12. #include "db.h"
  13. #include "xtypes.h"
  14. #include "appres.h"
  15. #include "query.h"
  16. #include "browser.h"
  17. #include "selection.h"
  18. #include "display.h"
  19. #include "ftp-actions.h"
  20. #include "alert.h"
  21. #include "status.h"
  22. #include "debug.h"
  23. extern DbEntry *db;
  24.  
  25. /*
  26.  * Functions defined here:
  27.  */
  28. void resetBrowser();
  29. int paneDepth();
  30. void selectBrowserItem(),unselectBrowserItem();
  31. void displayEntries();
  32. void resortBrowser();
  33. int openBrowserAll(),openBrowserDirectories(),openBrowserFiles();
  34. void shiftBrowserDown(), shiftBrowserUp(), shiftBrowserTop();
  35. void setBrowserState();
  36. int getBrowserState();
  37.  
  38. static void clearInfoForDepth(),displayInfoForDepth();
  39. static void updateButtons(),resetParentEntries();
  40. static void openBrowserDirectory();
  41.  
  42. /*
  43.  * Data defined here:
  44.  */
  45. /*
  46.  * These are the parents of the heads of the lists being displayed in
  47.  * the browser panes.
  48.  */
  49. static DbEntry *parentEntries[MAX_DEPTH];
  50.  
  51. /*
  52.  * This is the index of the leftmost pane's contents in the previous arrays.
  53.  */
  54. static int currentRootDepth;
  55.  
  56. static int browserState;
  57.  
  58. /*    -    -    -    -    -    -    -    -    */
  59.  
  60. void
  61. resetBrowser()
  62. {
  63.     clearBrowser();
  64.     currentRootDepth = 0;
  65.     resetSelections(0);
  66.     resetParentEntries(0);
  67.     setUpSensitive(0);
  68.     setDownSensitive(0);
  69. }
  70.  
  71. int
  72. paneDepth(pane)
  73. int pane;
  74. {
  75.     return(currentRootDepth+pane);
  76. }
  77.  
  78. #ifdef DEBUG
  79. /*ARGSUSED*/
  80. static void
  81. doPrint(dbp,list_index)
  82. DbEntry dbp;
  83. int list_index;
  84. {
  85.     printf("%d ",list_index);
  86. }
  87. #endif
  88.  
  89. void
  90. selectBrowserItem(pane,item)
  91. int pane,item;
  92. {
  93.     DbEntry *dbp;
  94.     int depth;
  95.     
  96.     /* Adjust for shifted browser */
  97.     depth = paneDepth(pane);
  98. #ifdef DEBUG
  99.     fprintf(stderr,"selecting item %d, pane=%d, depth=%d\n",item,pane,depth);
  100.     fprintf(stderr,"  before: selections[] = ");
  101.     if (hasSelection(depth))
  102.     forEachSelectedItemAtDepth(depth,doPrint);
  103.     else
  104.     fprintf(stderr,"None");
  105.     fprintf(stderr,"\n");
  106. #endif
  107.     if (isSelected(depth,item)) {
  108.     DEBUG1("item %d already selected\n",item);
  109.     return;
  110.     }
  111.     dbp = findEntryFromIndex(parentEntries[depth],item);
  112.     DEBUG2("selected item is \"%s\"(%lx)\n",dbp->name,dbp);
  113.     DEBUG1("clearing parents depth >= %d\n",depth+1);
  114.     resetParentEntries(depth+1);
  115.     DEBUG1("resetting selections for depth >= %d\n",depth+1);
  116.     resetSelections(depth+1);
  117.     DEBUG3("adding selection at depth %d = \"%s\"(%lx)\n",depth,dbp->name,dbp);
  118.     addSelection(depth,dbp,item);
  119.     DEBUG3("setting parentEntries[%d] = \"%s\"(%lx)\n",depth+1,dbp->name,dbp);
  120.     parentEntries[depth+1] = dbp;
  121.     DEBUG3("displaying entry \"%s\"(%lx) in pane %d\n",dbp->name,dbp,pane);
  122.     /* Highlight the selected item */
  123.     redrawSelectionsForPane(pane);
  124.     /* Show selected info */
  125.     displayInfoForDepth(depth);
  126.     /* If we're not at the rightmost pane, then show the choices. */
  127.     if (pane < NUM_BROWSER_PANES-1) {
  128.     displayEntries(dbp,pane+1);
  129.     }
  130. #ifdef DEBUG
  131.     fprintf(stderr,"  after: selections[] = ");
  132.     if (hasSelection(depth))
  133.     forEachSelectedItemAtDepth(depth,doPrint);
  134.     else
  135.     fprintf(stderr,"None");
  136.     fprintf(stderr,"\n");
  137.     fprintf(stderr,"done selecting item\n");
  138. #endif
  139. }
  140.  
  141. void
  142. unselectBrowserItem(pane,item)
  143. int pane,item;
  144. {
  145.      int depth,i;
  146.     
  147.     /* Adjust for shifted browser */
  148.     depth = paneDepth(pane);
  149. #ifdef DEBUG
  150.     fprintf(stderr,"unselecting item %d, pane=%d, depth=%d\n",item,pane,depth);
  151.     fprintf(stderr,"  before: selections[] = ");
  152.     if (hasSelection(depth))
  153.     forEachSelectedItemAtDepth(depth,doPrint);
  154.     else
  155.     fprintf(stderr,"None");
  156.     fprintf(stderr,"\n");
  157. #endif
  158.     unhighlightBrowserItem(pane,item);
  159.     /* Clear all panes below this one */
  160.     for (i=NUM_BROWSER_PANES-1; i > pane; i--)
  161.     clearBrowserPane(i);
  162.     /* Clear all info including this one since de-selected */
  163.     clearInfoForDepth(depth);
  164.     DEBUG2("removing selection at depth %d = item %d\n",depth,item);
  165.     removeSelection(depth,NULL,item);
  166.     DEBUG1("clearing parents depth >= %d\n",depth+1);
  167.     resetParentEntries(depth+1);
  168. #ifdef DEBUG
  169.     printf("  after: selections[] = ");
  170.     if (hasSelection(depth))
  171.     forEachSelectedItemAtDepth(depth,doPrint);
  172.     else
  173.     printf("None");
  174.     printf("\n");
  175.     fprintf(stderr,"done deselecting item\n");
  176. #endif
  177. }
  178.  
  179. static void
  180. clearInfoForDepth(depth)
  181. int depth;
  182. {
  183.     switch (depth) {
  184.     case 0:    setHostText("");
  185.         /* fall through */
  186.     case 1:    setLocationText("");
  187.         /* fall through */
  188.     case 2:    setFileText("");
  189.         setSizeText("");
  190.         setModesText("");
  191.         setDateText("");
  192.         break;
  193.     }
  194.     DEBUG1("cleared info for depth %d\n",depth);
  195. }
  196.  
  197. static void
  198. displayInfoForDepth(depth)
  199. int depth;
  200. {
  201.     SelectedItem *item;
  202.     char buf[MAX_VPATH];
  203.     int i;
  204.  
  205.     DEBUG1("  display info for depth %d:\n",depth);
  206.     if ((item=getSelection(0)) != NULL) {
  207.     setHostText(item->entry->name);
  208.     DEBUG1("    host: \"%s\"\n",item->entry->name);
  209.     }
  210.     /* Special case if location was selected */
  211.     if (depth == 1) {
  212.     if ((item=getSelection(1)) != NULL) {
  213.         setLocationText(item->entry->name);
  214.         DEBUG1("    loc: \"%s\"\n",item->entry->name);
  215.     }
  216.     } else {    /* Otherwise normal case, get location and file */
  217.     strcpy(buf,"");
  218.     for (i=1; i < depth; i++)
  219.         if ((item=getSelection(i)) != NULL) {
  220.         (void)strcat(buf,item->entry->name);
  221.         if (i < depth-1 &&
  222.             buf[strlen(buf)-1] != '/')
  223.             strcat(buf,"/");
  224.         }
  225.     setLocationText(buf);
  226.     DEBUG1("    loc: \"%s\"\n",buf);
  227.     if ((item=getSelection(depth)) != NULL) {
  228.         setFileText(item->entry->name);
  229. #ifdef MSDOS
  230.         sprintf(buf,"%lu",item->entry->size);
  231. #else
  232.         sprintf(buf,"%d",item->entry->size);
  233. #endif
  234.         setSizeText(buf);
  235.         setModesText(item->entry->modes);
  236.         setDateText(item->entry->date);
  237.         DEBUG1("    file: \"%s\"\n",item->entry->name);
  238.     }
  239.     }
  240. }
  241.  
  242. void
  243. displayEntries(parent,pane)
  244. DbEntry *parent;
  245. int pane;
  246. {
  247.     DbEntry *dbp;
  248.     SelectedItem *sel;
  249.     int i,depth;
  250.  
  251.     depth = paneDepth(pane);
  252.     if (parent == NULL) {
  253.     fprintf(stderr,"DB error: attempt to display entries from NULL list");
  254.     return;
  255.     }
  256.     DEBUG3("displaying parent \"%s\" in pane %d (depth %d)\n",
  257.        (parent?parent->name:"<NIL>"),pane,depth);
  258.     /* Clear this and all subordinate panes */
  259.     for (i=pane; i < NUM_BROWSER_PANES; i++) {
  260.     DEBUG1("  clearing pane %d\n",i);
  261.     clearBrowserPane(i);
  262.     }
  263.     /* Set the strings to be displayed in this pane */
  264.     for (i=0, dbp=parent->entries; dbp != NULL; dbp=dbp->next) {
  265.     DEBUG2("  item %d: \"%s\"\n",i,dbp->name);
  266.     setBrowserItem(pane,i++,dbp->name);
  267.     }
  268.     /* If there's anything to display, display it */
  269.     if (i > 0)
  270.     redrawBrowserPane(pane);
  271.     /* If there's only one thing then select it */
  272.     if (i == 1) {
  273.     DEBUG0("  solo -> select\n");
  274.     addSelection(depth,parent->entries,0);
  275.     }
  276.     /* If there's something selected (either because we just selected the
  277.        only thing or because we're scrolling left), then redo the
  278.        highlighting and display the correct info. If we're not at the
  279.        rightmost pane, then recusively draw the next pane. */
  280.     if ((sel=getSelection(depth)) != NULL) {
  281.     redrawSelectionsForPane(pane);
  282.     displayInfoForDepth(depth);
  283.     if (pane < NUM_BROWSER_PANES - 1)
  284.         displayEntries(sel->entry,pane+1);
  285.     } else {
  286.     /* Otherwise there's nothing selected here */
  287.     clearInfoForDepth(depth);
  288.     }
  289.     /* Save which list is being displayed in the pane */
  290.     parentEntries[paneDepth(pane)] = parent;
  291.     /* Get the shift buttons right */
  292.     updateButtons();
  293. }
  294.  
  295. static void
  296. updateButtons()
  297. {
  298.     SelectedItem *sel;
  299.  
  300.     setUpSensitive(currentRootDepth > 0);
  301.     if ((sel=getSelection(currentRootDepth+NUM_BROWSER_PANES-1)) != NULL &&
  302.     sel->entry->entries != NULL)
  303.     setDownSensitive(1);
  304.     else
  305.     setDownSensitive(0);
  306. }
  307.  
  308. static void
  309. resetParentEntries(first)
  310. int first;
  311. {
  312.     int i;
  313.  
  314.     for (i=first; i < MAX_DEPTH; i++)
  315.     parentEntries[i] = NULL;
  316. }
  317.  
  318. /*    -    -    -    -    -    -    -    -    */
  319. /* Resort the browser based on the appResources */
  320.  
  321. void
  322. resortBrowser()
  323. {
  324.     /* Reset browser to leftmost position */
  325.     DEBUG0("resortBrowser: resetting browser\n");
  326.     resetBrowser();
  327.     DEBUG0("resortBrowser: sorting entries\n");
  328.     switch(appResources.sortType) {
  329.     case GfName:
  330.         sortEntriesRecursively(db,cmpEntryNames);
  331.         break;
  332.     case GfDate:
  333.         sortEntriesRecursively(db,cmpEntryDates);
  334.         break;
  335.     case GfWeight:
  336.         sortEntriesRecursively(db,cmpEntryWeights);
  337.         break;
  338.     }
  339.     /* Display results in browser */
  340.     DEBUG0("resortBrowser: displaying entries\n");
  341.     displayEntries(db,0);
  342.     DEBUG0("resortBrowser: done\n");
  343. }
  344.  
  345. /*    -    -    -    -    -    -    -    -    */
  346. /* Routines to open (ie. expand) the browser */
  347.  
  348. static int numOpened;
  349.  
  350. /*
  351.  * Open any selected items in the browser. Return the number of items
  352.  * that were successfully opened.
  353.  */
  354. int
  355. openBrowserAll()
  356. {
  357.     DEBUG1("openBrowserAll: depth = %d\n",currentRootDepth);
  358.     if (!hasSelection(NUM_BROWSER_PANES-1)) {
  359.     alert0("You must select something to open.");
  360.     return(0);
  361.     }
  362.     numOpened = 0;
  363.     /* Do the directories */
  364.     forEachSelectedItem(openBrowserDirectory);
  365.     /* Do the files */
  366.     ftpOpenSelectedItems();
  367.     DEBUG1("done openBrowserAll, returning %d\n",numOpened);
  368.     return(numOpened);
  369. }
  370.  
  371. int
  372. openBrowserDirectories()
  373. {
  374.     DEBUG1("openBrowserDirectories: depth = %d\n",currentRootDepth);
  375.     if (!hasSelection(2)) {
  376.     alert0("You must select a directory to open.");
  377.     return(0);
  378.     }
  379.     numOpened = 0;
  380.     forEachSelectedItem(openBrowserDirectory);
  381.     status0("Ready");
  382.     DEBUG1("done openBrowserDirectories, returning %d\n",numOpened);
  383.     return(numOpened);
  384. }
  385.  
  386. int
  387. openBrowserFiles()
  388. {
  389.     DEBUG1("openBrowserFiles: depth = %d\n",currentRootDepth);
  390.     if (!hasSelection(2)) {
  391.     alert0("You must select a file to open.");
  392.     return(0);
  393.     }
  394.     numOpened = 0;
  395.     ftpOpenSelectedItems();
  396.     DEBUG1("done openBrowserFiles, returning %d\n",numOpened);
  397.     return(numOpened);
  398. }
  399.  
  400. /*
  401.  * Open a selected item. Ignore any selections that aren't directories.
  402.  */
  403. /*ARGSUSED*/
  404. static void
  405. openBrowserDirectory(dbp,list_index)
  406. DbEntry *dbp;
  407. int list_index;
  408. {
  409.     VLINK vl,links;
  410.  
  411.     DEBUG1("openBrowserDirectory: \"%s\"\n",dbp->name);
  412.     if (dbp->type != DB_DIRECTORY)
  413.     return;
  414.     if (dbp->entries == NULL) {
  415.     /* It's not been expanded already... */
  416.     if ((vl=dbp->vlink) == NULL) {
  417.         alert0("ERROR: NULL vlink to openBrowserDirectory!");
  418.         return;
  419.     }
  420.     /* Disable querying */
  421.     setBrowserState(BROWSER_DIRSEND);
  422.     DEBUG1("getting entries for \"%s\"\n",dbp->name);
  423.     links = stringQuery(vl->host,vl->filename);
  424.     DEBUG0("calling handleProsperoErrors\n");
  425.     (void)handleProsperoErrors();
  426.     if (links != NULL)
  427.         numOpened += 1;
  428. #ifdef DEBUG
  429.     fprintf(stderr,"unprocessed results of stringQuery:\n");
  430.     for (vl=links; vl != NULL; vl=vl->next)
  431.         fprintf(stderr,"  \"%s\"\n",vl->filename);
  432.     fprintf(stderr,"calling parseStringQueryResults\n");
  433. #endif
  434.     /* Process the results into the database */
  435.     switch(appResources.sortType) {
  436.         case GfName:
  437.         (void)parseStringQueryResults(dbp,links,cmpEntryNames);
  438.         break;
  439.         case GfDate:
  440.         (void)parseStringQueryResults(dbp,links,cmpEntryDates);
  441.         break;
  442.         case GfWeight:
  443.         (void)parseStringQueryResults(dbp,links,cmpEntryWeights);
  444.         break;
  445.     }
  446.     /* Re-enable querying */
  447.     setBrowserState(BROWSER_READY);
  448.     }
  449.     DEBUG0("done openBrowserDirectory\n");
  450. }
  451.  
  452. /*    -    -    -    -    -    -    -    -    */
  453. /* Routines for shifting the browser up, down, top. */
  454.  
  455. void
  456. shiftBrowserDown()
  457. {
  458.     DEBUG1("doing shiftDown, depth = %d\n",currentRootDepth);
  459.     if (currentRootDepth >= MAX_DEPTH-1) {
  460.     alert1("Browser only goes %d levels deep!",(char *)MAX_DEPTH);
  461.     return;
  462.     }
  463.     if (parentEntries[currentRootDepth+1] == NULL) {
  464.     alert0("Nothing to display below!");
  465.     return;
  466.     }
  467.     currentRootDepth += 1;
  468.     DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
  469.     displayEntries(parentEntries[currentRootDepth],0);
  470.     DEBUG0("done shiftDown\n");
  471. }
  472.  
  473. void
  474. shiftBrowserUp()
  475. {
  476.     DEBUG1("doing shiftUp, depth = %d\n",currentRootDepth);
  477.     if (currentRootDepth == 0) {
  478.     beep();
  479.     return;
  480.     }
  481.     currentRootDepth -= 1;
  482.     DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
  483.     displayEntries(parentEntries[currentRootDepth],0);
  484.     DEBUG0("done shiftUp\n");
  485. }
  486.  
  487. void
  488. shiftBrowserTop()
  489. {
  490.     DEBUG1("doing shiftTop, depth = %d\n",currentRootDepth);
  491.     currentRootDepth = 0;
  492.     DEBUG1("currentRootDepth is now %d\n",currentRootDepth);
  493.     displayEntries(db,0);
  494.     DEBUG0("done shiftTop\n");
  495. }
  496.  
  497. /*    -    -    -    -    -    -    -    -    */
  498. /* Routines for getting/setting the state of the browser */
  499. /*
  500.  * Non-zero state => busy
  501.  */
  502.  
  503. void
  504. setBrowserState(state)
  505. int state;
  506. {
  507.     setQuerySensitive(state == BROWSER_READY);
  508.     setAbortSensitive(state != BROWSER_READY);
  509.     browserState = state;
  510. }
  511.  
  512. int
  513. getBrowserState()
  514. {
  515.     return(browserState);
  516. }
  517.  
  518.